/*
 * Copyright (c) 2022. All rights reserved.
 * Please don't try to modify the code, because I don't know what the consequences will be.
 *
 *
 *
 *
 *
 *
 *
 */

package cc.zzone.bean;

import cc.zzone.util.SpringMVCUtil;
import com.alibaba.fastjson2.JSON;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 日志拦截器
 *
 * @author jinzhengze
 * @since 2023年1月30日
 */
@Slf4j
@Component
public class LogRecordInterceptor implements HandlerInterceptor {

    @Override
    @SuppressWarnings("NullableProblems")
    public void afterCompletion(HttpServletRequest request,
                                HttpServletResponse response,
                                Object handler,
                                Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
        if (!(handler instanceof HandlerMethod))
            return;
        Map<String, Object> info = new LinkedHashMap<>();
        info.put("method", request.getMethod());
        info.put("path", request.getRequestURI());
        info.put("localAddress", request.getLocalAddr());
        info.put("remoteAddress", SpringMVCUtil.getClientIp(request));
        Map<String, String> headers = new LinkedHashMap<>();
        Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String nextElement = headerNames.nextElement();
            headers.put(nextElement, request.getHeader(nextElement));
        }
        info.put("headers", headers);
        info.put("params", JSON.toJSONString(request.getParameterMap()));
        info.put("payload", JSON.parse(SpringMVCUtil.getRequestBody(request)));
        String responseBody = SpringMVCUtil.getResponseBody(response);
        if (response.containsHeader(HttpHeaders.CONTENT_DISPOSITION))
            info.put("body", "[\"Binary File\"]");
        else {
            try {
                Object parse = JSON.parse(responseBody);
                info.put("body", parse);
            } catch (Exception e) {
                info.put("body", responseBody);
            }
        }
        log.info("Request : {}", info);
    }
}
